<template>
  <div class="chat-container">
    <!-- 顶部导航栏（不变） -->
    <el-header class="chat-header">
      <div class="header-content">
        <div class="logo">
          <span>DeepSeek Chat</span>
        </div>
        <div class="header-actions">
          <el-button type="success" icon="el-icon-refresh" @click="resetConversation">新对话</el-button>
          <el-button type="primary" icon="el-icon-picture" @click="showChartForm = true">
            手动生成图表
          </el-button>
        </div>
      </div>
    </el-header>

    <!-- 主聊天区域（新增：调试文本 + 强制渲染） -->
    <el-main class="chat-main">
      <div class="message-container" ref="messageContainer">
        <!-- 欢迎消息（不变） -->
        <div class="welcome-message" v-if="messages.length === 0">
          <h2>欢迎使用 DeepSeek Chat</h2>
          <p>我是您的AI助手，可以回答各种问题、帮助创作和提供建议<br>支持可视化企业财报/数据（输入"可视化A公司2021-2023年营收"体验）
          </p>
          <div class="quick-questions">
            <el-button
              v-for="(question, index) in quickQuestions"
              :key="index"
              round
              @click="sendQuickQuestion(question)"
            >
              {{ question }}
            </el-button>
            <el-button round
                       @click="sendQuickQuestion('可视化A公司2021-2023年营收：2021年1000万，2022年1500万，2023年2200万')">
              可视化财报示例
            </el-button>
          </div>
        </div>

        <!-- 消息列表（新增：调试文本，确认chartUrl是否存在） -->
        <div
          v-for="(message, index) in messages"
          :key="index"
          class="message-item"
          :class="{'user-message': message.role === 'user', 'ai-message': message.role === 'assistant'}"
        >
          <div class="message-avatar">
            <img v-if="message.role === 'user'" src="../../assets/images/user.jpeg" alt="User">
            <img v-else src="../../assets/images/bot.jpeg" alt="AI">
          </div>
          <div class="message-content">
            <!-- 1. 文本消息渲染（不变） -->
            <div class="message-text" v-html="formatMessage(message.content)"></div>

            <!-- 【新增调试】显示chartUrl是否存在（方便定位问题，可后续删除） -->
            <div v-if="message.role === 'assistant'" style="font-size: 12px; color: #666; margin-top: 8px;">
              调试：chartUrl是否存在 → {{ message.chartUrl ? '是（' + message.chartUrl.slice(0, 50) + '...）' : '否' }}
            </div>

            <!-- 2. 图表渲染（强制判断chartUrl，确保有值就渲染） -->
            <div class="chart-container" v-if="message.role === 'assistant' && message.chartUrl">
              <iframe
                :src="message.chartUrl"
                width="100%"
                height="400px"
                frameborder="0"
                class="chart-iframe"
                :title="`图表-${index}`"
              ></iframe>
            </div>
            <div class="chart-container" v-else-if="message.role === 'assistant' && message.echartsOption">
              <div :ref="`chartRef-${index}`" class="chart-echarts" style="width: 100%; height: 400px;"></div>
            </div>

            <!-- 原有消息操作栏（不变） -->
            <div class="message-actions">
              <el-button
                v-if="message.role === 'assistant'"
                type="text"
                icon="el-icon-copy-document"
                size="mini"
                @click="copyToClipboard(message.content + (message.chartUrl ? `\n图表链接：${message.chartUrl}` : ''))"
              >
                复制
              </el-button>
              <el-button type="text" icon="el-icon-thumb" size="mini" @click="rateMessage(index, 'like')"
                         :class="{active: message.rating === 'like'}">
                {{ message.likes || 0 }}
              </el-button>
              <el-button type="text" icon="el-icon-thumb" size="mini" @click="rateMessage(index, 'dislike')"
                         :class="{active: message.rating === 'dislike'}">
                {{ message.dislikes || 0 }}
              </el-button>
              <span class="message-time">{{ formatTime(message.timestamp) }}</span>
            </div>
          </div>
        </div>

        <!-- 加载指示器（不变） -->
        <div class="loading-indicator" v-if="isLoading">
          <span>AI正在思考...</span>
        </div>
      </div>
    </el-main>

    <!-- 输入区域（不变） -->
    <el-footer class="chat-footer">
      <div class="input-container">
        <el-input
          type="textarea"
          :rows="2"
          :autosize="{ minRows: 2, maxRows: 6 }"
          placeholder="输入您的问题...（支持可视化需求，如'随机生成财务图表'）"
          v-model="inputMessage"
          @keyup.enter.native="sendMessage"
          :disabled="isLoading"
          ref="inputArea"
        ></el-input>
        <div class="input-actions">
          <el-button type="primary" :loading="isLoading" @click="sendMessage" :disabled="!inputMessage.trim()">
            发送
          </el-button>
        </div>
      </div>
      <div class="footer-notice">
        <span>DeepSeek Chat 可能会产生不准确的信息，请谨慎验证</span>
      </div>
    </el-footer>

    <!-- 手动生成图表弹窗（不变） -->
    <el-dialog
      :visible.sync="showChartForm"
      title="手动生成数据可视化图表"
      width="70%"
      :close-on-click-modal="false"
    >
      <ChartForm @submitChartData="handleSubmitChartData" @cancel="showChartForm = false"></ChartForm>
    </el-dialog>
  </div>
</template>

<script>
import {marked} from 'marked'
import DOMPurify from 'dompurify'
import * as echarts from 'echarts'
import ChartForm from './ChartForm.vue'

export default {
  name: 'ChatPage',
  components: {ChartForm},
  data() {
    return {
      messages: [],
      inputMessage: '',
      isLoading: false,
      showSettings: false,
      quickQuestions: [
        "如何学习Vue.js?",
        "写一封辞职信模板",
        "推荐几个Python学习资源",
        "解释一下量子计算的基本概念"
      ],
      responseLength: 3,
      enableWebSearch: false,
      showChartForm: false,
      chartInstances: {}
    }
  },
  methods: {
    sendMessage() {
      if (!this.inputMessage.trim() || this.isLoading) return;

      // 1. 推送用户消息
      const userMessage = {
        role: 'user',
        content: this.inputMessage,
        timestamp: new Date()
      };
      this.messages.push(userMessage);
      this.inputMessage = '';
      this.isLoading = true;
      this.$nextTick(() => this.scrollToBottom());

      const self = this;
      this.$http.get("/chat/", {params: {"question": userMessage.content}})
        .then(function (rs) {
          self.isLoading = false;
          if (rs.data.code === 200) {
            let aiContent = rs.data.data || '';
            const aiMessage = {
              role: 'assistant',
              content: aiContent,
              timestamp: new Date(),
              chartUrl: '',
              echartsOption: null,
              likes: 0,
              dislikes: 0,
              rating: null
            };

            // 【核心修改：直接匹配文本中的完整 JSON 对象（{开头，}结尾）】
            try {
              console.log("=== 提取文本中的 JSON ===");
              console.log("AI 回复原始文本：", aiContent);

              // 1. 匹配完整 JSON（{开头，}结尾，贪婪匹配）
              const jsonRegex = /(\{[\s\S]*\})/;
              const matchResult = aiContent.match(jsonRegex);
              if (!matchResult || !matchResult[1]) {
                console.warn("未在文本中找到 JSON 对象（{...}）");
                aiMessage.content += '<br><br><span style="color:#f56c6c;">⚠️ 未找到图表配置</span>';
                return;
              }

              // 2. 解析 JSON
              const pureJsonStr = matchResult[1].trim();
              const echartsConfig = JSON.parse(pureJsonStr);
              console.log("JSON 解析成功，配置：", echartsConfig);

              // 3. 【核心：获取图表类型（从 series[0].type 判断）】
              let chartType = "";
              if (echartsConfig.series && Array.isArray(echartsConfig.series) && echartsConfig.series.length > 0) {
                chartType = echartsConfig.series[0].type || "";
              }
              if (!chartType) {
                throw new Error("未找到图表类型（series[0].type 缺失）");
              }
              console.log("当前图表类型：", chartType);

              // 4. 【动态定义必需字段（按图表类型）】
              let requiredFields = [];
              if (chartType === "pie") {
                // 饼图必需字段：仅需 title/tooltip/legend/series（无 xAxis/yAxis）
                requiredFields = ["title", "tooltip", "legend", "series"];
              } else if (["line", "bar"].includes(chartType)) {
                // 折线/柱状图必需字段：需包含 xAxis/yAxis
                requiredFields = ["title", "tooltip", "legend", "series", "xAxis", "yAxis"];
              } else {
                throw new Error(`不支持的图表类型：${chartType}（仅支持 pie/line/bar）`);
              }

              // 5. 校验必需字段是否缺失
              const missingFields = requiredFields.filter(field => !echartsConfig[field]);
              if (missingFields.length > 0) {
                throw new Error(`缺少 ${chartType} 图表必需字段：${missingFields.join(", ")}`);
              }

              // 6. 额外校验 series 格式（必须是数组且非空）
              if (!Array.isArray(echartsConfig.series) || echartsConfig.series.length === 0) {
                throw new Error("series 必须是非空数组");
              }

              // 7. 校验通过：赋值配置并优化回复文本
              aiMessage.echartsOption = echartsConfig;
              console.log("ECharts 配置验证通过，准备渲染");
              // 隐藏原始 JSON，提升用户体验
              aiMessage.content = aiContent.replace(pureJsonStr, '').trim() +
                '<br><br><span style="color:#409eff;">✅ 图表已渲染在下方</span>';

            } catch (jsonError) {
              console.error("JSON 处理失败：", jsonError);
              aiMessage.content += `<br><br><span style="color:#f56c6c;">⚠️ 图表配置错误：${jsonError.message}</span>`;
            }

            // 2. 推送 AI 消息并渲染图表
            self.messages.push(aiMessage);
            self.$nextTick(() => {
              self.scrollToBottom();
              // 若有合法配置，触发渲染
              if (aiMessage.echartsOption) {
                const chartIndex = self.messages.length - 1;
                self.renderECharts(chartIndex, aiMessage.echartsOption);
              }
            });

          } else {
            self.messages.push({
              role: 'assistant',
              content: `<span style="color:#f56c6c;">后端错误：${rs.data.message}</span>`,
              timestamp: new Date()
            });
            self.scrollToBottom();
          }
        })
        .catch(function (httpError) {
          self.isLoading = false;
          self.messages.push({
            role: 'assistant',
            content: `<span style="color:#f56c6c;">请求失败：${httpError.message || '网络异常'}</span>`,
            timestamp: new Date()
          });
          self.scrollToBottom();
        });
    },

    // 以下方法完全不变（省略重复代码，保持原有逻辑）
    sendQuickQuestion(question) {
      this.inputMessage = question;
      this.sendMessage();
    },
    resetConversation() {
      this.$confirm('确定要开始新的对话吗?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        Object.values(this.chartInstances).forEach(instance => instance.dispose());
        this.chartInstances = {};
        this.messages = [];
      });
    },
    scrollToBottom() {
      const container = this.$refs.messageContainer;
      container.scrollTop = container.scrollHeight;
    },
    formatMessage(content) {
      // 【关键：过滤掉所有Markdown图片标签，避免残留】
      const filteredContent = content.replace(/!\[\]\((http:\/\/localhost:8000\/show_chart\/\?option=.+?)\)/, '');
      return DOMPurify.sanitize(marked.parse(filteredContent || ''));
    },
    formatTime(timestamp) {
      return new Date(timestamp).toLocaleTimeString([], {hour: '2-digit', minute: '2-digit'});
    },
    copyToClipboard(text) {
      navigator.clipboard.writeText(text).then(() => this.$message.success('已复制到剪贴板'));
    },
    rateMessage(index, type) {
      const message = this.messages[index];
      if (type === 'like') {
        if (message.rating === 'like') {
          message.rating = null;
          message.likes--;
        } else {
          if (message.rating === 'dislike') message.dislikes--;
          message.rating = 'like';
          message.likes++;
        }
      } else {
        if (message.rating === 'dislike') {
          message.rating = null;
          message.dislikes--;
        } else {
          if (message.rating === 'like') message.likes--;
          message.rating = 'dislike';
          message.dislikes++;
        }
      }
    },
    focusInput() {
      this.$refs.inputArea.focus();
    },
    // 重点修改 renderECharts 方法，其他方法（如 sendMessage）无需修改
    renderECharts(chartIndex, echartsOption) {
      console.log(`=== 渲染图表（索引：${chartIndex}）===`);
      const chartRefKey = `chartRef-${chartIndex}`;

      // 【核心修复：处理 $refs 可能返回数组的情况】
      let chartDom = this.$refs[chartRefKey];
      // 如果是数组，取第一个元素（通常只有一个匹配元素）
      if (Array.isArray(chartDom) && chartDom.length > 0) {
        chartDom = chartDom[0];
        console.log(`从数组中提取 DOM 元素：${chartRefKey}[0]`);
      }

      // 1. 校验 DOM 有效性（此时 chartDom 应为单个元素）
      if (!chartDom || !(chartDom instanceof HTMLElement)) {
        console.error(`DOM 无效：${chartRefKey}`, chartDom);
        return;
      }

      // 2. 后续逻辑不变（获取宽高、渲染图表等）
      const computedStyle = window.getComputedStyle(chartDom);
      const offsetWidth = chartDom.offsetWidth;
      const offsetHeight = chartDom.offsetHeight;
      console.log(`DOM 实际宽高：${offsetWidth}px × ${offsetHeight}px`);

      try {
        // 3. 初始化 ECharts（此时 DOM 宽高已确保有效）
        const chartInstance = echarts.init(chartDom);
        console.log("ECharts 实例初始化成功（版本：", echarts.version, "）");

        // 4. 【关键】添加配置调试：简化配置，排除复杂参数影响
        const simpleOption = {
          title: echartsOption.title,
          tooltip: echartsOption.tooltip,
          legend: echartsOption.legend,
          // 简化 grid：确保图表在容器内（避免超出范围导致空白）
          grid: {
            left: "10%", // 左内边距（避免坐标轴超出）
            right: "10%",
            bottom: "20%",
            top: "20%",
            containLabel: true // 确保标签不超出容器
          },
          xAxis: echartsOption.xAxis,
          yAxis: echartsOption.yAxis,
          series: echartsOption.series
        };
        console.log("简化后的 ECharts 配置：", simpleOption);

        // 5. 渲染并强制适配
        chartInstance.setOption(simpleOption);
        // 延迟 100ms 再 resize（确保 DOM 完全渲染后适配）
        setTimeout(() => {
          chartInstance.resize();
          console.log("图表已延迟适配宽高");
        }, 100);

        // 6. 缓存实例并监听缩放
        this.chartInstances[chartIndex] = chartInstance;
        const resizeHandler = () => {
          if (this.chartInstances[chartIndex]) {
            this.chartInstances[chartIndex].resize();
          }
        };
        window.addEventListener('resize', resizeHandler);

        // 7. 组件销毁时清理
        this.$once('hook:beforeDestroy', () => {
          window.removeEventListener('resize', resizeHandler);
          if (this.chartInstances[chartIndex]) {
            this.chartInstances[chartIndex].dispose();
          }
        });

      } catch (err) {
        console.error("图表渲染失败（完整错误）：", err);
        // 显示详细错误提示
        if (chartDom instanceof HTMLElement) {
          chartDom.innerHTML = '';
          const errorDiv = document.createElement('div');
          errorDiv.style.cssText = `
        width:100%; height:400px; padding:20px; display:flex; flex-direction:column;
        align-items:center; justify-content:center; color:#f56c6c; background:#fff;
        border:1px solid #ebeef5; border-radius:8px; box-sizing:border-box;
      `;
          errorDiv.innerHTML = `
        <div>图表渲染失败</div>
        <div style="margin-top:10px; font-size:12px; text-align:center;">
          错误原因：${err.message}<br>
          请查看控制台日志获取详细信息
        </div>
      `;
          chartDom.appendChild(errorDiv);
        }
      }
    },
    handleSubmitChartData(formData) {
      this.showChartForm = false;
      this.isLoading = true;
      const userMessage = {
        role: 'user',
        content: `手动生成图表：${formData.title}（类型：${formData.chartType === 'line' ? '折线图' : formData.chartType === 'bar' ? '柱状图' : '饼图'}）`,
        timestamp: new Date()
      };
      this.messages.push(userMessage);
      const self = this;
      this.$http.post("/generate_chart/", formData)
        .then(rs => {
          if (rs.data.code === 200) {
            const {echartsOption, chartUrl} = rs.data;
            const aiMessage = {
              role: 'assistant',
              content: '已为您生成手动提交数据的可视化图表：',
              timestamp: new Date(),
              chartUrl: chartUrl || '',
              echartsOption: echartsOption || null,
              likes: 0,
              dislikes: 0,
              rating: null
            };
            self.messages.push(aiMessage);
            self.$nextTick(() => {
              self.scrollToBottom();
              if (echartsOption) self.renderECharts(self.messages.length - 1, echartsOption);
            });
          } else {
            self.messages.push({
              role: 'assistant',
              content: `图表生成失败：${rs.data.msg}`,
              timestamp: new Date(),
              likes: 0,
              dislikes: 0,
              rating: null
            });
          }
        })
        .catch(err => {
          self.messages.push({
            role: 'assistant',
            content: `图表生成请求失败：${err.message}`,
            timestamp: new Date(),
            likes: 0,
            dislikes: 0,
            rating: null
          });
        })
        .finally(() => {
          self.isLoading = false;
          self.scrollToBottom();
        });
    }
  },
  beforeDestroy() {
    Object.values(this.chartInstances).forEach(instance => instance.dispose());
  },
  mounted() {
    this.focusInput();
  }
}
</script>

<style scoped>
@import url('../../assets/css/chat.css');

.chart-echarts {
  display: block; /* 块级元素，避免 inline 导致宽高失效 */
  width: 100% !important; /* 强制占满父容器宽度 */
  height: 400px !important; /* 固定高度，避免被父元素挤压 */
  margin-top: 12px; /* 与文本间距，避免重叠 */
  box-sizing: border-box; /* 确保 padding 不影响宽高 */
}

/* 确保图表容器的父元素有足够宽度 */
.message-content {
  width: 100%;
  max-width: 800px; /* 限制最大宽度，避免图表过宽 */
  margin: 0 auto;
}
</style>
